package com.apes.enquiry.supplierUser;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.logger.ApesLoggerService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.rop.session.SimpleSession;
import com.apes.framework.util.MD5Util;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.repository.BranchRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.rbac.model.*;
import com.apes.scm.rbac.repository.LocalPermitRepository;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.RoleRepository;
import com.apes.scm.rbac.repository.UserRepository;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 类描述：供应商询价平台用户管理
 *
 * @ClassName UserService
 * @Description 描述
 * @Author wushilong
 * @Date 2022/9/21 9:50
 * @Version 1.0
 */
@Service
public class SupplierUserService extends DomainService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ApesLoggerService apesLoggerService;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    LocalPermitRepository localPermitRepository;

    @Autowired
    private PartyRoleRepository partyRoleRepository;

    @Autowired
    private BranchRepository branchRepository;

    @Autowired
    private SequenceService sequenceService;

    @Autowired
    private PostRepository postRepository;

    @Autowired
    private PartyRepository partyRepository;

    @Autowired
    private EnumerationRepository enumerationRepository;

    /**
     * 询价平台界面创建用户账号
     *
     * @param request
     * @return
     */
    public User newUser(SimpleRequest request) {

        //获取注册用户信息
        User user = getUser(request);

        //初始化用户基础数据
        initUser(user, request);

        //设置用户默认密码、公钥、私钥、私钥过期时间。
        basicsData(user);

        //查询数据库是否禁用进行对比，发生改变进行写入日志
        whetherForbidden(request, user);

        //保存用户（注册账号）
        User result = null;
        try {
            result = userRepository.saveAndFlush(user);
            result.setPostLits(user.getPostLits());
        } catch (Exception e) {
            String errorMessage = e.toString();
            if (errorMessage.contains("ORA-00001") && errorMessage.contains("YYGYS.SUPP_USER_MOBILENUMBER"))
                throw new RuntimeException("电话号码已存在请勿重复创建！");
            else throw new RuntimeException(e.toString());
        }
        return result;
    }

    /**
     * 从 ERP 系统创建供应商询价平台账号
     *
     * @param request
     */
    public String weirdUser(SimpleRequest request) {
        //获取注册用户信息
        User user = JSON.parseObject(request.getJO().toJSONString(), User.class);

        //初始化用户基础数据
        initUser(user, null);

        //设置用户默认密码、公钥、私钥、私钥过期时间。
        basicsData(user);

        //查询数据库是否禁用进行对比，发生改变进行写入日志
        whetherForbidden(request, user);

        //当事人不存在则创建
        if (Objects.isNull(partyRepository.findOne(user.getPerson().getParty().getId()))) {
            user.getPerson().setParty(partyRepository.save(user.getPerson().getParty()));
        }

        //创建供应商
        user.setPerson(partyRoleRepository.save(user.getPerson()));

        //保存用户（注册账号）
        User result = null;
        try {
            result = userRepository.saveAndFlush(user);
            result.setPostLits(user.getPostLits());
        } catch (Exception e) {
            String errorMessage = e.toString();
            if (errorMessage.contains("ORA-00001") && errorMessage.contains("YYGYS.SUPP_USER_MOBILENUMBER"))
                throw new RuntimeException("电话号码已存在请勿重复创建！");
            else throw new RuntimeException(e.toString());
        }

        return result.getOrigin();
    }

    /**
     * 获取供应商询价平台用户注册信息
     *
     * @param request
     * @return
     */
    private User getUser(SimpleRequest request) {
        User user;
        user = new User();
        user.setName(request.getJO().getJSONObject("result").getString("name"));
        user.setMobileNumber(request.getJO().getJSONObject("result").getString("mobileNumber"));
        user.setPerson(request.getO("person", PartyRole.class));
        int size = userRepository.findAll(JpaDsl.toCriteriaByEq("person.id", request.getPersonId())).size() + 1;
        String sort = size < 10 ? "0" + size : "" + size;
        user.setOrigin("G" + user.getPerson().getId() + sort);
        return user;
    }

    /**
     * 查询数据库是否禁用进行对比，发生改变进行写入日志
     *
     * @param request
     * @param user
     */
    private void whetherForbidden(SimpleRequest request, User user) {
        //查询数据库是否禁用进行对比，发生改变进行写入日志
        if (user.getId() == null) return;

        User temp = userRepository.findOne(user.getId());
        if (user.isDisable() != temp.isDisable()) {
            if (user.isDisable()) {
                SimpleSession session = request.getSession();
                apesLoggerService.sendSynEvent("event:ir.logger.create", MapUtil.mapper("businessType", "User",
                        "businessKey", user.getId(), "operate", "禁用角色", "workPostName", null, "operator_id", 1));
            } else {
                apesLoggerService.sendSynEvent("event:ir.logger.create", MapUtil.mapper("businessType", "User",
                        "businessKey", user.getId(), "operate", "启用角色", "workPostName", null, "operator_id", 1));
            }
        }
    }

    /**
     * 设置用户默认密码、公钥、私钥、私钥过期时间。
     *
     * @param user
     */
    private void basicsData(User user) {
        // 默认 default123 的md5 密码
        String password = Optional.ofNullable(user.getPassword()).orElse("e9335e177b288c7af4af8f1225c3f938");
        if (user.getAccessId() == null) { // 新建时
            // 公钥 操作员账号 + 随机字符串 加密
            String accessId = user.getOrigin() + ":" + RandomStringUtils.randomAlphanumeric(10);
            user.setAccessId(accessId);
            // 私钥
            String accessKey = MD5Util.encrypt(RandomStringUtils.randomAlphanumeric(16));
            user.setAccessKey(accessKey);
            // 私钥有效期止
            updateUserValidityTime(user, LocalDateTime.now().plusYears(1));
        }

        user.setPassword(password);
    }

    /**
     * ERP平台创建供应商平台用户>>>初始化用户基础数据
     * 供应商平台绑定本地角色
     * @param user
     */
    private void initUser(User user, SimpleRequest request) {

        if (Objects.isNull(request)) {
            //初始化该供应商所有本地角色
            Map<String,String> mapper = MapUtil.mapper("管理员", "Supplier_Admin", "数据管理员", "Supplier_DataAdmin", "业务员", "Supplier_Sales");
            mapper.forEach((k, y) -> {
                Post post = new Post();
                String id = "";
                switch (k){
                    case "管理员":id="001";
                    break;
                    case "数据管理员":id="002";
                    break;
                    case "业务员":id="003";
                    break;
                }
                post.setId(user.getPerson().getId() + id);
                post.setName(k);
                //设置公司和部门
                PartyRole company = partyRoleRepository.findOne("00002560");
                post.setCompany(company);
                Branch branch = branchRepository.findOne("1001000000");
                post.setBranch(branch);

                //初始化本地权限
                LocalPermit localPermit = new LocalPermit();
                localPermit.setId(user.getPerson().getId());
                localPermit.setName(user.getPerson().getName());
                //初始化本地权限明细
                LocalPermitItem localPermitItem = new LocalPermitItem();
                localPermitItem.setType(enumerationRepository.findOne("pt_supplier"));
                localPermitItem.setPurpose(enumerationRepository.findOne("pp_belong"));
                localPermitItem.setOrgId(localPermit.getId());
                localPermitItem.setOrgName(localPermit.getName());
                localPermitItem.setLocalPermit(localPermit);
                //将本地权限明细与本地权限绑定
                localPermit.getLocalPermitItems().add(localPermitItem);
                localPermit = localPermitRepository.save(localPermit);
                post.setLocalPermit(localPermit);
                //绑定通用角色
                Role role = roleRepository.findOne(y);
                post.getRoles().add(role);
                //保存本地角色
                post = postRepository.save(post);
                //用户绑定本地角色
                if ("管理员".equals(k)) user.getPosts().add(post);
            });

        } else {
            //供应商平台创建账号添加对应的本地角色
            JSONArray roles = request.getJO().getJSONObject("result").getJSONArray("role");
            roles.stream().forEach(role -> {
                JSONObject roleJSON = (JSONObject) role;
                String name = roleJSON.getString("name");
                String personId = request.getPersonId();
                switch (name){
                    case "管理员":{
                        Post post = postRepository.findOne(personId + "001");
                        user.getPosts().add(post);
                        break;
                    }
                    case "数据管理员":{
                        Post post = postRepository.findOne(personId + "002");
                        user.getPosts().add(post);
                        break;
                    }
                    case "业务员":{
                        Post post = postRepository.findOne(personId + "003");
                        user.getPosts().add(post);
                        break;
                    }
                }
            });
        }
    }

    /**
     * 设置私钥有效期止
     *
     * @param user
     * @param localDateTime
     */
    private void updateUserValidityTime(User user, LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        Date date = Date.from(zdt.toInstant());
        user.setValidityTime(date);
    }

    /**
     * 查询供应商附属账号
     *
     * @param request
     * @return List<User>
     */
    public List<User> findAllUser(SimpleRequest request) {
        if ("yyadmin".equals(request.get("id"))) return userRepository.findAll();
        List<String> supplierIds = Collections.singletonList(request.get("id").toString());
        return userRepository.findAllBySupplier(supplierIds);
    }

    /**
     * 供应商账号设置编辑按钮
     *
     * @param request
     * @return
     */
    public List<User> updateUser(SimpleRequest request) {
        //修改账号基础信息
        User newUser = request.getJO().getObject("result", User.class);
        User user = userRepository.findOne(newUser.getId());
        user.setName(newUser.getName());
        user.setMobileNumber(newUser.getMobileNumber());
        user.getPosts().clear();

        //修改账号角色
        JSONArray roles = request.getJO().getJSONArray("role");
        roles.stream().forEach( json -> {
            if (Objects.isNull(json))return;
            JSONObject role = (JSONObject) json;
            String name = role.getString("name");
            String personId = user.getPerson().getId();
            switch (name){
                case "管理员":{
                    Post post = postRepository.findOne(personId + "001");
                    user.getPosts().add(post);
                    break;
                }
                case "数据管理员":{
                    Post post = postRepository.findOne(personId + "002");
                    user.getPosts().add(post);
                    break;
                }
                case "业务员":{
                    Post post = postRepository.findOne(personId + "003");
                    user.getPosts().add(post);
                    break;
                }
            }
        });
        try{
        userRepository.saveAndFlush(user);
    } catch (Exception e) {
        String errorMessage = e.toString();
        if (errorMessage.contains("ORA-00001") && errorMessage.contains("YYGYS.SUPP_USER_MOBILENUMBER"))
            throw new RuntimeException("修改失败!该手机号已被使用");
        else throw new RuntimeException(e.toString());
    }
        return findAllUser(request);
    }

    /**
     * 供应商账号密码重置与启用禁用
     *
     * @param request
     * @return
     *///96e79218965eb72c92a549dd5a330112
    public List<User> accountUserButton(SimpleRequest request) {
        Integer id = Integer.valueOf(request.getJO().getString("result"));
        User user = userRepository.findOne(id);
        String letter = request.getJO().getString("value");
        if ("pwd".equals(letter)) user.setPassword("e9335e177b288c7af4af8f1225c3f938");

        if (!"pwd".equals(letter)) user.setDisable(Boolean.parseBoolean(letter));

        userRepository.saveAndFlush(user);
        return findAllUser(request);
    }

    /**
     * 删除用户
     *
     * @param request
     */
    public void delete(SimpleRequest request) {
        Integer id = request.get("id");
        User user = userRepository.findOne(id);
        userRepository.delete(user);
    }

}
